<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 21 Discover Webpack and NPM | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.21 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 21 Discover Webpack and NPM | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 21 Discover Webpack and NPM | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2021-04-19" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="webpack-intro.html"/>
<link rel="next" href="packer-overview.html"/>
<script src="libs/jquery-3.5.1/jquery.min.js"></script>
<link href="libs/gitbook-2.6.7/css/style.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/htmlwidgets-1.5.3/htmlwidgets.js"></script>
<script src="libs/plotly-binding-4.9.3/plotly.js"></script>
<script src="libs/typedarray-0.1/typedarray.min.js"></script>
<link href="libs/crosstalk-1.1.1/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk-1.1.1/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css-1.57.1/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main-1.57.1/plotly-latest.min.js"></script>
<script src="libs/core-js-2.5.3/shim.min.js"></script>
<script src="libs/react-16.12.0/react.min.js"></script>
<script src="libs/react-16.12.0/react-dom.min.js"></script>
<script src="libs/reactwidget-1.0.0/react-tools.js"></script>
<script src="libs/reactable-binding-0.2.3/reactable.js"></script>
<script src="libs/r2d3-render-0.1.0/r2d3-render.js"></script>
<script src="libs/webcomponents-2.0.0/webcomponents.js"></script>
<script src="libs/r2d3-binding-0.2.5/r2d3.js"></script>
<script src="libs/d3v6-6.2.0/d3.min.js"></script>
<script src="libs/viz-1.8.2/viz.js"></script>
<link href="libs/DiagrammeR-styles-0.2/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding-1.0.6.1/grViz.js"></script>
<link href="libs/datatables-css-0.0.0/datatables-crosstalk.css" rel="stylesheet" />
<script src="libs/datatables-binding-0.17/datatables.js"></script>
<link href="libs/dt-core-1.10.20/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="libs/dt-core-1.10.20/css/jquery.dataTables.extra.css" rel="stylesheet" />
<script src="libs/dt-core-1.10.20/js/jquery.dataTables.min.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-74544116-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-74544116-1');
</script>
<meta property="og:title" content="Chapter 21 Discover Webpack and NPM | JavaScript for R">
<meta property="og:description" content="Book on using JavaScript with R for visualisations, web development, and computations.">
<meta property="og:image" content="https://book.javascript-for-r.com/images/social.png">
<meta property="og:url" content="https://book.javascript-for-r.com/">
<meta name="twitter:card" content="summary_large_image">
<meta property="og:site_name" content="Chapter 21 Discover Webpack and NPM | JavaScript for R">
<meta name="twitter:image:alt" content="Book on using JavaScript with R for visualisations, web development, and computations.">
<meta name="twitter:site" content="@jdatap">


<style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a><ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
</ul></li>
<li class="part"><span><b>I Basics and Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="intro-overview.html"><a href="intro-overview.html"><i class="fa fa-check"></i><b>1</b> Overview</a><ul>
<li class="chapter" data-level="1.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-overview-rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a><ul>
<li class="chapter" data-level="1.2.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="intro-overview.html"><a href="intro-overview.html#intro-shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="intro-overview.html"><a href="intro-overview.html#intro-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a><ul>
<li class="chapter" data-level="1.3.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-reactr-vuer"><i class="fa fa-check"></i><b>1.3.1</b> reactR &amp; vueR</a></li>
<li class="chapter" data-level="1.3.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a><ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-package-dev"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a><ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-create-pkg"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#basics-documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#basics-installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#basics-build-load-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-json"><i class="fa fa-check"></i><b>2.2</b> JSON</a><ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-tabular"><i class="fa fa-check"></i><b>2.2.2</b> Tabular Data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a><ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-chrome-devtools"><i class="fa fa-check"></i><b>2.3.1</b> Developer Tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-var-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable Declaration and Scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document Object Model</a></li>
</ul></li>
<li class="chapter" data-level="2.4" data-path="prerequisites.html"><a href="prerequisites.html#basics-shiny"><i class="fa fa-check"></i><b>2.4</b> Shiny</a><ul>
<li class="chapter" data-level="2.4.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-static-files"><i class="fa fa-check"></i><b>2.4.1</b> Serving Static Files</a></li>
<li class="chapter" data-level="2.4.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-htmltools"><i class="fa fa-check"></i><b>2.4.2</b> Htmltools</a></li>
<li class="chapter" data-level="2.4.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-deps-pro-cons"><i class="fa fa-check"></i><b>2.4.3</b> Serving vs. htmltools</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html"><i class="fa fa-check"></i><b>3</b> Introduction to Widgets</a><ul>
<li class="chapter" data-level="3.1" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-plotly"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-dt"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
<li class="chapter" data-level="3.3" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-crosstalk"><i class="fa fa-check"></i><b>3.3</b> Crosstalk</a></li>
<li class="chapter" data-level="3.4" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-conclude"><i class="fa fa-check"></i><b>3.4</b> Wrap-up</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="widgets-basics.html"><a href="widgets-basics.html"><i class="fa fa-check"></i><b>4</b> Basics of Building Widgets</a><ul>
<li class="chapter" data-level="4.1" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-study"><i class="fa fa-check"></i><b>4.1</b> Read and Study</a></li>
<li class="chapter" data-level="4.2" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates"><i class="fa fa-check"></i><b>4.2</b> Candidate Libraries</a><ul>
<li class="chapter" data-level="4.2.1" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-plotly"><i class="fa fa-check"></i><b>4.2.1</b> Plotly.js</a></li>
<li class="chapter" data-level="4.2.2" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-highcharts"><i class="fa fa-check"></i><b>4.2.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.2.3" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-chart.js"><i class="fa fa-check"></i><b>4.2.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.3" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-inner-workings"><i class="fa fa-check"></i><b>4.3</b> How It Works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="widgets-first.html"><a href="widgets-first.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a><ul>
<li class="chapter" data-level="5.1" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-htmloutput"><i class="fa fa-check"></i><b>5.2</b> The HTML Output</a></li>
<li class="chapter" data-level="5.3" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-js-files"><i class="fa fa-check"></i><b>5.3</b> JavaScript Files</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="widgets-realistic.html"><a href="widgets-realistic.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a><ul>
<li class="chapter" data-level="6.1" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-deps"><i class="fa fa-check"></i><b>6.1</b> Dependencies</a></li>
<li class="chapter" data-level="6.2" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-implementation"><i class="fa fa-check"></i><b>6.2</b> Implementation</a></li>
<li class="chapter" data-level="6.3" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-html-element"><i class="fa fa-check"></i><b>6.3</b> HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="widgets-full.html"><a href="widgets-full.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a><ul>
<li class="chapter" data-level="7.1" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-deps"><i class="fa fa-check"></i><b>7.1</b> Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-js"><i class="fa fa-check"></i><b>7.2</b> JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a><ul>
<li class="chapter" data-level="7.4.1" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-js"><i class="fa fa-check"></i><b>7.4.1</b> Using JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-modify"><i class="fa fa-check"></i><b>7.4.2</b> Modify Serialiser</a></li>
<li class="chapter" data-level="7.4.3" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-replace"><i class="fa fa-check"></i><b>7.4.3</b> Replace Serialiser</a></li>
<li class="chapter" data-level="7.4.4" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-modify-data"><i class="fa fa-check"></i><b>7.4.4</b> Modify the Data</a></li>
<li class="chapter" data-level="7.4.5" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-conclusion"><i class="fa fa-check"></i><b>7.4.5</b> Pros and Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-on-print"><i class="fa fa-check"></i><b>7.5</b> On Print Method</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="widgets-adv.html"><a href="widgets-adv.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a><ul>
<li class="chapter" data-level="8.1" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-shared"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a><ul>
<li class="chapter" data-level="8.1.1" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-prerender"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks and Security</a></li>
<li class="chapter" data-level="8.4" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-js"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-prepend-append"><i class="fa fa-check"></i><b>8.5</b> Prepend and Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="linking-widgets.html"><a href="linking-widgets.html"><i class="fa fa-check"></i><b>9</b> Linking Widgets</a><ul>
<li class="chapter" data-level="9.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-examples"><i class="fa fa-check"></i><b>9.1</b> Crosstalk Examples</a></li>
<li class="chapter" data-level="9.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-req"><i class="fa fa-check"></i><b>9.2</b> Crosstalk Requirements</a></li>
<li class="chapter" data-level="9.3" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-inner-workings"><i class="fa fa-check"></i><b>9.3</b> How it Works</a><ul>
<li class="chapter" data-level="9.3.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-keys"><i class="fa fa-check"></i><b>9.3.1</b> Keys</a></li>
<li class="chapter" data-level="9.3.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-communication-lines"><i class="fa fa-check"></i><b>9.3.2</b> Communication Lines</a></li>
<li class="chapter" data-level="9.3.3" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-groups"><i class="fa fa-check"></i><b>9.3.3</b> Groups</a></li>
</ul></li>
<li class="chapter" data-level="9.4" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with Gio</a></li>
<li class="chapter" data-level="9.5" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-r"><i class="fa fa-check"></i><b>9.5</b> R code</a></li>
<li class="chapter" data-level="9.6" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-js"><i class="fa fa-check"></i><b>9.6</b> JavaScript Code</a><ul>
<li class="chapter" data-level="9.6.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-send-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send Selected Keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-set-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set Selected Keys</a></li>
</ul></li>
<li class="chapter" data-level="9.7" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-using"><i class="fa fa-check"></i><b>9.7</b> Using Crosstalk with Gio</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="widgets-final.html"><a href="widgets-final.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a><ul>
<li class="chapter" data-level="10.1" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-data"><i class="fa fa-check"></i><b>10.1</b> Htmlwidgets and Data</a></li>
<li class="chapter" data-level="10.2" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of Options</a></li>
<li class="chapter" data-level="10.3" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-interface"><i class="fa fa-check"></i><b>10.3</b> Interface Design</a></li>
<li class="chapter" data-level="10.4" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-exercises"><i class="fa fa-check"></i><b>10.4</b> Exercises</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="11" data-path="shiny-intro.html"><a href="shiny-intro.html"><i class="fa fa-check"></i><b>11</b> Bidirectional Communication</a><ul>
<li class="chapter" data-level="11.1" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-websocket"><i class="fa fa-check"></i><b>11.1</b> WebSocket an Shiny</a></li>
<li class="chapter" data-level="11.2" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-sessions"><i class="fa fa-check"></i><b>11.2</b> Sessions</a></li>
<li class="chapter" data-level="11.3" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-example"><i class="fa fa-check"></i><b>11.3</b> Alerts, an example</a><ul>
<li class="chapter" data-level="11.3.1" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-explore"><i class="fa fa-check"></i><b>11.3.1</b> Explore</a></li>
<li class="chapter" data-level="11.3.2" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-r-to-js"><i class="fa fa-check"></i><b>11.3.2</b> From R to JavaScript</a></li>
<li class="chapter" data-level="11.3.3" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-serialise"><i class="fa fa-check"></i><b>11.3.3</b> Serialisation</a></li>
<li class="chapter" data-level="11.3.4" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-js2r"><i class="fa fa-check"></i><b>11.3.4</b> JavaScript to R</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="12" data-path="shiny-complete.html"><a href="shiny-complete.html"><i class="fa fa-check"></i><b>12</b> A Complete Integration</a><ul>
<li class="chapter" data-level="12.1" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-discover"><i class="fa fa-check"></i><b>12.1</b> Discover</a></li>
<li class="chapter" data-level="12.2" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-setup"><i class="fa fa-check"></i><b>12.2</b> Setup</a></li>
<li class="chapter" data-level="12.3" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-dependencies"><i class="fa fa-check"></i><b>12.3</b> Dependencies</a></li>
<li class="chapter" data-level="12.4" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-images"><i class="fa fa-check"></i><b>12.4</b> Static Files</a></li>
<li class="chapter" data-level="12.5" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-skeleton"><i class="fa fa-check"></i><b>12.5</b> Skeleton</a></li>
<li class="chapter" data-level="12.6" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-r2js"><i class="fa fa-check"></i><b>12.6</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.7" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-js2r"><i class="fa fa-check"></i><b>12.7</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.8" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-input-handler"><i class="fa fa-check"></i><b>12.8</b> Input handler</a></li>
<li class="chapter" data-level="12.9" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg"><i class="fa fa-check"></i><b>12.9</b> As a Package</a><ul>
<li class="chapter" data-level="12.9.1" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-deps"><i class="fa fa-check"></i><b>12.9.1</b> Dependencies</a></li>
<li class="chapter" data-level="12.9.2" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-trigger"><i class="fa fa-check"></i><b>12.9.2</b> Trigger classification</a></li>
<li class="chapter" data-level="12.9.3" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-js-code"><i class="fa fa-check"></i><b>12.9.3</b> JavaScript code</a></li>
<li class="chapter" data-level="12.9.4" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-input-handler"><i class="fa fa-check"></i><b>12.9.4</b> Input handler</a></li>
<li class="chapter" data-level="12.9.5" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-test"><i class="fa fa-check"></i><b>12.9.5</b> Test</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="13" data-path="shiny-tips.html"><a href="shiny-tips.html"><i class="fa fa-check"></i><b>13</b> Tips and Tricks</a><ul>
<li class="chapter" data-level="13.1" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-events"><i class="fa fa-check"></i><b>13.1</b> Shiny Events</a></li>
<li class="chapter" data-level="13.2" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-table-btn"><i class="fa fa-check"></i><b>13.2</b> Table Buttons</a></li>
<li class="chapter" data-level="13.3" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-jQuery"><i class="fa fa-check"></i><b>13.3</b> jQuery</a></li>
</ul></li>
<li class="chapter" data-level="14" data-path="shiny-output.html"><a href="shiny-output.html"><i class="fa fa-check"></i><b>14</b> Custom Outputs</a><ul>
<li class="chapter" data-level="14.1" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-inner-workings"><i class="fa fa-check"></i><b>14.1</b> Inner-workings</a></li>
<li class="chapter" data-level="14.2" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-setup"><i class="fa fa-check"></i><b>14.2</b> Setup</a></li>
<li class="chapter" data-level="14.3" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-r-fun"><i class="fa fa-check"></i><b>14.3</b> Output R Function</a></li>
<li class="chapter" data-level="14.4" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-html"><i class="fa fa-check"></i><b>14.4</b> Generate Output HTML</a></li>
<li class="chapter" data-level="14.5" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-renderer"><i class="fa fa-check"></i><b>14.5</b> Output Renderer</a></li>
<li class="chapter" data-level="14.6" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-binding"><i class="fa fa-check"></i><b>14.6</b> JavaScript Output Binding</a><ul>
<li class="chapter" data-level="14.6.1" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-title"><i class="fa fa-check"></i><b>14.6.1</b> Boxxy Title</a></li>
<li class="chapter" data-level="14.6.2" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-value"><i class="fa fa-check"></i><b>14.6.2</b> Boxxy Value</a></li>
<li class="chapter" data-level="14.6.3" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-bg-color"><i class="fa fa-check"></i><b>14.6.3</b> Boxxy Background Color</a></li>
<li class="chapter" data-level="14.6.4" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-register"><i class="fa fa-check"></i><b>14.6.4</b> Register the Output Binding</a></li>
</ul></li>
<li class="chapter" data-level="14.7" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-usage"><i class="fa fa-check"></i><b>14.7</b> Boxxy Usage</a></li>
<li class="chapter" data-level="14.8" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-inject"><i class="fa fa-check"></i><b>14.8</b> Injecting Dependencies</a></li>
<li class="chapter" data-level="14.9" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-preprocess"><i class="fa fa-check"></i><b>14.9</b> Preprocessing Custom Outputs</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="shiny-input.html"><a href="shiny-input.html"><i class="fa fa-check"></i><b>15</b> Custom Inputs</a><ul>
<li class="chapter" data-level="15.1" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-setup"><i class="fa fa-check"></i><b>15.1</b> Setup</a></li>
<li class="chapter" data-level="15.2" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-intro"><i class="fa fa-check"></i><b>15.2</b> Switch Input HTML and Style</a></li>
<li class="chapter" data-level="15.3" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-html"><i class="fa fa-check"></i><b>15.3</b> Generate Input HTML</a></li>
<li class="chapter" data-level="15.4" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-binding"><i class="fa fa-check"></i><b>15.4</b> JavaScript Input Binding</a><ul>
<li class="chapter" data-level="15.4.1" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-find"><i class="fa fa-check"></i><b>15.4.1</b> Find Inputs</a></li>
<li class="chapter" data-level="15.4.2" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-get-id"><i class="fa fa-check"></i><b>15.4.2</b> Get Input Id</a></li>
<li class="chapter" data-level="15.4.3" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-get-value"><i class="fa fa-check"></i><b>15.4.3</b> Get Input Value</a></li>
<li class="chapter" data-level="15.4.4" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-set-value"><i class="fa fa-check"></i><b>15.4.4</b> Set Input Value</a></li>
<li class="chapter" data-level="15.4.5" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-receive-msg"><i class="fa fa-check"></i><b>15.4.5</b> Receive Input Messages</a></li>
<li class="chapter" data-level="15.4.6" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-sub-unsub"><i class="fa fa-check"></i><b>15.4.6</b> Subscribe and Unsubscribe Inputs</a></li>
<li class="chapter" data-level="15.4.7" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-rate-policy"><i class="fa fa-check"></i><b>15.4.7</b> Input Rate Policy</a></li>
<li class="chapter" data-level="15.4.8" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-register"><i class="fa fa-check"></i><b>15.4.8</b> Registering the Input Binding</a></li>
</ul></li>
<li class="chapter" data-level="15.5" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-update"><i class="fa fa-check"></i><b>15.5</b> Update Input</a></li>
<li class="chapter" data-level="15.6" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-excercise"><i class="fa fa-check"></i><b>15.6</b> Exercise</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="shiny-cookies.html"><a href="shiny-cookies.html"><i class="fa fa-check"></i><b>16</b> Cookies</a><ul>
<li class="chapter" data-level="16.1" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-discover"><i class="fa fa-check"></i><b>16.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="16.2" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-setup"><i class="fa fa-check"></i><b>16.2</b> Setup Project</a></li>
<li class="chapter" data-level="16.3" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-javascript"><i class="fa fa-check"></i><b>16.3</b> JavaScript Cookies</a></li>
<li class="chapter" data-level="16.4" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-r-code"><i class="fa fa-check"></i><b>16.4</b> R Code</a></li>
<li class="chapter" data-level="16.5" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-exercises"><i class="fa fa-check"></i><b>16.5</b> Exercises</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="shiny-widgets.html"><a href="shiny-widgets.html"><i class="fa fa-check"></i><b>17</b> Widgets with Shiny</a><ul>
<li class="chapter" data-level="17.1" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-to-r"><i class="fa fa-check"></i><b>17.1</b> Widgets to R</a></li>
<li class="chapter" data-level="17.2" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-handlers"><i class="fa fa-check"></i><b>17.2</b> Input Handlers for Widgets</a></li>
<li class="chapter" data-level="17.3" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-r-to-widgets"><i class="fa fa-check"></i><b>17.3</b> R to Widgets</a><ul>
<li class="chapter" data-level="17.3.1" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-send-data"><i class="fa fa-check"></i><b>17.3.1</b> Send Data from Widgets</a></li>
<li class="chapter" data-level="17.3.2" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-retrieve"><i class="fa fa-check"></i><b>17.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="17.3.3" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-handle-data"><i class="fa fa-check"></i><b>17.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="17.4" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-proxy"><i class="fa fa-check"></i><b>17.4</b> Proxy Function</a></li>
<li class="chapter" data-level="17.5" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-clear-data"><i class="fa fa-check"></i><b>17.5</b> Clear Data</a></li>
<li class="chapter" data-level="17.6" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-update"><i class="fa fa-check"></i><b>17.6</b> Update the Widget</a></li>
</ul></li>
<li class="part"><span><b>IV JavaScript for Computations</b></span></li>
<li class="chapter" data-level="18" data-path="v8.html"><a href="v8.html"><i class="fa fa-check"></i><b>18</b> The V8 Engine</a><ul>
<li class="chapter" data-level="18.1" data-path="v8.html"><a href="v8.html#v8-installation"><i class="fa fa-check"></i><b>18.1</b> Installation</a></li>
<li class="chapter" data-level="18.2" data-path="v8.html"><a href="v8.html#v8-basics"><i class="fa fa-check"></i><b>18.2</b> Basics</a></li>
<li class="chapter" data-level="18.3" data-path="v8.html"><a href="v8.html#v8-external"><i class="fa fa-check"></i><b>18.3</b> External Libraries</a></li>
<li class="chapter" data-level="18.4" data-path="v8.html"><a href="v8.html#v8-npm"><i class="fa fa-check"></i><b>18.4</b> NPM Packages</a></li>
<li class="chapter" data-level="18.5" data-path="v8.html"><a href="v8.html#v8-pkg"><i class="fa fa-check"></i><b>18.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="19" data-path="v8-ml.html"><a href="v8-ml.html"><i class="fa fa-check"></i><b>19</b> Machine Learning</a><ul>
<li class="chapter" data-level="19.1" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-dependency"><i class="fa fa-check"></i><b>19.1</b> Dependency</a></li>
<li class="chapter" data-level="19.2" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-regression"><i class="fa fa-check"></i><b>19.2</b> Simple Regression</a></li>
<li class="chapter" data-level="19.3" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-exercises"><i class="fa fa-check"></i><b>19.3</b> Exercises</a></li>
</ul></li>
<li class="part"><span><b>V Robust JavaScript</b></span></li>
<li class="chapter" data-level="20" data-path="webpack-intro.html"><a href="webpack-intro.html"><i class="fa fa-check"></i><b>20</b> Managing JavaScript</a><ul>
<li class="chapter" data-level="20.1" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-example"><i class="fa fa-check"></i><b>20.1</b> Example</a></li>
<li class="chapter" data-level="20.2" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-browser"><i class="fa fa-check"></i><b>20.2</b> Transpiling</a></li>
<li class="chapter" data-level="20.3" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-minification"><i class="fa fa-check"></i><b>20.3</b> Minification</a></li>
<li class="chapter" data-level="20.4" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-structure"><i class="fa fa-check"></i><b>20.4</b> Bundling and Modules</a></li>
<li class="chapter" data-level="20.5" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-decouple"><i class="fa fa-check"></i><b>20.5</b> Decoupling</a></li>
<li class="chapter" data-level="20.6" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-npm"><i class="fa fa-check"></i><b>20.6</b> NPM</a></li>
<li class="chapter" data-level="20.7" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-conclude"><i class="fa fa-check"></i><b>20.7</b> With R</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html"><i class="fa fa-check"></i><b>21</b> Discover Webpack and NPM</a><ul>
<li class="chapter" data-level="21.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install"><i class="fa fa-check"></i><b>21.1</b> Installation</a><ul>
<li class="chapter" data-level="21.1.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-mac"><i class="fa fa-check"></i><b>21.1.1</b> Mac OS</a></li>
<li class="chapter" data-level="21.1.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-ubuntu"><i class="fa fa-check"></i><b>21.1.2</b> Ubuntu</a></li>
<li class="chapter" data-level="21.1.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-windows"><i class="fa fa-check"></i><b>21.1.3</b> Windows</a></li>
<li class="chapter" data-level="21.1.4" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-other"><i class="fa fa-check"></i><b>21.1.4</b> Other</a></li>
</ul></li>
<li class="chapter" data-level="21.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-setup"><i class="fa fa-check"></i><b>21.2</b> Set Up the App</a></li>
<li class="chapter" data-level="21.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-init-npm"><i class="fa fa-check"></i><b>21.3</b> Initialise NPM</a></li>
<li class="chapter" data-level="21.4" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-pkgs"><i class="fa fa-check"></i><b>21.4</b> Installing NPM Packages</a></li>
<li class="chapter" data-level="21.5" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-entry-points"><i class="fa fa-check"></i><b>21.5</b> Entry Point and Output</a></li>
<li class="chapter" data-level="21.6" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-conf"><i class="fa fa-check"></i><b>21.6</b> Configuration File</a></li>
<li class="chapter" data-level="21.7" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-npm-scripts"><i class="fa fa-check"></i><b>21.7</b> NPM scripts</a></li>
<li class="chapter" data-level="21.8" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-webpack-mode"><i class="fa fa-check"></i><b>21.8</b> Source maps</a></li>
<li class="chapter" data-level="21.9" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-bundle"><i class="fa fa-check"></i><b>21.9</b> Bundle</a></li>
<li class="chapter" data-level="21.10" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-internal-dependencies"><i class="fa fa-check"></i><b>21.10</b> Internal Dependencies</a></li>
<li class="chapter" data-level="21.11" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-external-dependencies"><i class="fa fa-check"></i><b>21.11</b> External Dependencies</a></li>
<li class="chapter" data-level="21.12" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export"><i class="fa fa-check"></i><b>21.12</b> Import and Export</a><ul>
<li class="chapter" data-level="21.12.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-named"><i class="fa fa-check"></i><b>21.12.1</b> Named</a></li>
<li class="chapter" data-level="21.12.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-default"><i class="fa fa-check"></i><b>21.12.2</b> Default</a></li>
<li class="chapter" data-level="21.12.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-wrap-up"><i class="fa fa-check"></i><b>21.12.3</b> Wrap-up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="22" data-path="packer-overview.html"><a href="packer-overview.html"><i class="fa fa-check"></i><b>22</b> Webpack with R</a><ul>
<li class="chapter" data-level="22.1" data-path="packer-overview.html"><a href="packer-overview.html#packer-principles"><i class="fa fa-check"></i><b>22.1</b> Principles of packer</a></li>
<li class="chapter" data-level="22.2" data-path="packer-overview.html"><a href="packer-overview.html#packer-scaffolds"><i class="fa fa-check"></i><b>22.2</b> Scaffolds</a></li>
<li class="chapter" data-level="22.3" data-path="packer-overview.html"><a href="packer-overview.html#packer-inputs"><i class="fa fa-check"></i><b>22.3</b> Inputs</a></li>
<li class="chapter" data-level="22.4" data-path="packer-overview.html"><a href="packer-overview.html#packer-r-file"><i class="fa fa-check"></i><b>22.4</b> R file</a></li>
<li class="chapter" data-level="22.5" data-path="packer-overview.html"><a href="packer-overview.html#packer-js-files"><i class="fa fa-check"></i><b>22.5</b> JavaScript Files</a></li>
<li class="chapter" data-level="22.6" data-path="packer-overview.html"><a href="packer-overview.html#packer-bundle"><i class="fa fa-check"></i><b>22.6</b> Bundle</a></li>
</ul></li>
<li class="chapter" data-level="23" data-path="packer-adv.html"><a href="packer-adv.html"><i class="fa fa-check"></i><b>23</b> Webpack Advanced</a><ul>
<li class="chapter" data-level="23.1" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-widgets"><i class="fa fa-check"></i><b>23.1</b> Widgets</a></li>
<li class="chapter" data-level="23.2" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue"><i class="fa fa-check"></i><b>23.2</b> Shiny with Vue and Bootstrap 4</a><ul>
<li class="chapter" data-level="23.2.1" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-setup"><i class="fa fa-check"></i><b>23.2.1</b> Setup</a></li>
<li class="chapter" data-level="23.2.2" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-bs4"><i class="fa fa-check"></i><b>23.2.2</b> Bootstrap 4 Installation</a></li>
<li class="chapter" data-level="23.2.3" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-code"><i class="fa fa-check"></i><b>23.2.3</b> Vue Code</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>VI Closing Remarks</b></span></li>
<li class="chapter" data-level="24" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>24</b> Conclusion</a><ul>
<li class="chapter" data-level="24.1" data-path="conclusion.html"><a href="conclusion.html#conclusion-performances"><i class="fa fa-check"></i><b>24.1</b> Performances</a></li>
<li class="chapter" data-level="24.2" data-path="conclusion.html"><a href="conclusion.html#conclusion-trial-and-error"><i class="fa fa-check"></i><b>24.2</b> Trial and Error</a></li>
<li class="chapter" data-level="24.3" data-path="conclusion.html"><a href="conclusion.html#conclusion-ux"><i class="fa fa-check"></i><b>24.3</b> Functionality and UX</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="webpack-intro-discover" class="section level1">
<h1><span class="header-section-number">Chapter 21</span> Discover Webpack and NPM</h1>
<p>In this chapter, we discover how to feature webpack and NPM in a straightforward Shiny project. The idea is not to build a complex application, only to find out how one might go about bringing them into an R project and observe some of their benefits (and potential issues).</p>
<p>There is a lot of depth to NPM and webpack; we only touch upon the surface here so we can obtain a basic setup for a Shiny application. We’ll eventually go into slightly more detail as this part of the book progresses, but it will by no means fully explore the realm of webpack. It’s always a good idea to take a look at the <a href="https://webpack.js.org/">official documentation</a> to get a better picture of the technology.</p>
<div id="webpack-intro-install" class="section level2">
<h2><span class="header-section-number">21.1</span> Installation</h2>
<p>As Node’s Package Manager, a working installation of Node.js, is required, NPM ships with it. A bit like R in a sense where the package manager also comes with the language, install R, and you can install packages from CRAN with <code>install.packages</code>. The same applies here, install Node and you can install NPM packages from the command line.</p>
<div class="rmdnote">
<p>
We are only going to use Node.js <em>indirectly</em>, some of its functionalities and its package manager. This is not about building Node applications.
</p>
</div>
<p>Below are some directions on how to install Node.js. In the event this does not work or you encounter issues please refer to the <a href="https://nodejs.org/en/">official website</a>.</p>
<div id="webpack-intro-install-mac" class="section level3">
<h3><span class="header-section-number">21.1.1</span> Mac OS</h3>
<p>On Mac OS, the easiest way is via homebrew.</p>
<pre><code>brew update
brew install node</code></pre>
<p>Otherwise there is also an <a href="https://nodejs.org/en/download/">installer</a> available.</p>
</div>
<div id="webpack-intro-install-ubuntu" class="section level3">
<h3><span class="header-section-number">21.1.2</span> Ubuntu</h3>
<p>With Ubuntu one can install it straight from the package manager.</p>
<pre><code>sudo apt install nodejs</code></pre>
</div>
<div id="webpack-intro-install-windows" class="section level3">
<h3><span class="header-section-number">21.1.3</span> Windows</h3>
<p>Download and install the official <a href="https://nodejs.org/en/download/">executable</a> or use <a href="https://chocolatey.org/">chocolatey</a>.</p>
<pre><code>cinst nodejs.install</code></pre>
<p>Or use <a href="https://scoop.sh/">scoop</a>.</p>
<pre><code>scoop install nodejs</code></pre>
</div>
<div id="webpack-intro-install-other" class="section level3">
<h3><span class="header-section-number">21.1.4</span> Other</h3>
<p>If you are on another OS or Linux distro check the official, very concise <a href="https://nodejs.org/en/download/package-manager/">guide</a> to install from various package managers.</p>
</div>
</div>
<div id="webpack-intro-setup" class="section level2">
<h2><span class="header-section-number">21.2</span> Set Up the App</h2>
<p>Let us first put together a simple Shiny application that will serve as a basis for including webpack and npm. Create a new directory and in it place a file called <code>app.R</code> containing a very simple application.</p>
<div class="sourceCode" id="cb399"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb399-1" title="1"><span class="kw">library</span>(shiny)</a>
<a class="sourceLine" id="cb399-2" title="2"></a>
<a class="sourceLine" id="cb399-3" title="3">ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</a>
<a class="sourceLine" id="cb399-4" title="4">  <span class="kw">h1</span>(<span class="st">&quot;A shiny app&quot;</span>)</a>
<a class="sourceLine" id="cb399-5" title="5">)</a>
<a class="sourceLine" id="cb399-6" title="6"></a>
<a class="sourceLine" id="cb399-7" title="7">server &lt;-<span class="st"> </span><span class="cf">function</span>(...) {}</a>
<a class="sourceLine" id="cb399-8" title="8"></a>
<a class="sourceLine" id="cb399-9" title="9"><span class="kw">shinyApp</span>(ui, server)</a></code></pre></div>
</div>
<div id="webpack-intro-init-npm" class="section level2">
<h2><span class="header-section-number">21.3</span> Initialise NPM</h2>
<p>With a simple application, one can initialise NPM. This could be translated into the equivalent of starting a new project in R. This is done from the command line, <em>from the root of the directory</em> that you want to use as a project.</p>
<p>Whereas in R we previously used the usethis package to create packages with <code>create_package</code> or projects with <code>create_project</code>, NPM does not create the initial empty directory where the project will be created; you have to create the directory first then initialise a new project.</p>
<p>An NPM project can be initialised with the command <code>npm init</code>, which when run prompts the user with a few questions, such as the name of the project, the license to use, etc. These have little importance for what we do here but will matter if you decide to publish the package on NPM. One can also pass the “yes” flag to the function to skip those questions: <code>npm init -y</code>.</p>
<p>This creates a <code>package.json</code> file, which is loosely equivalent to the <code>DESCRIPTION</code> of an R package; it includes information on the dependencies of the project, the version of the project, and more.</p>
<p>We will revisit this file later in the chapter. At this stage ensure you have run <code>npm init</code> (with or without the <code>-y</code> flag) from the root of the project (where the <code>app.R</code> file is located).</p>
</div>
<div id="webpack-intro-install-pkgs" class="section level2">
<h2><span class="header-section-number">21.4</span> Installing NPM Packages</h2>
<p>Unless the R programmer uses packages such as renv <span class="citation">(Ushey <a href="#ref-R-renv">2020</a>)</span> or packrat <span class="citation">(Ushey et al. <a href="#ref-R-packrat">2018</a>)</span> then packages are installed globally on the machine, running <code>install.packages("dplyr")</code> installs a single version of dplyr across the entire device. Because CRAN is strict and its packages subsequently stable, it tends not to be too much of an issue. Packages submitted to CRAN are checked for reverse dependencies (other packages that depend on it) to see if the submission could cause problems downstream.</p>
<p>However, NPM does no such thing with packages that are submitted. Therefore the developer has to be more careful about dependencies, particularly versioning as packages can dramatically change from one version to the next. Thus it makes sense that NPM out-of-the-box advocates and provides tools to encapsulate projects. It is <em>not recommended,</em> to install NPM packages globally. NPM projects (the directory where <code>npm init</code> was run) come bundled with the equivalent of renv/packrat.</p>
<p>Installing Node packages also takes place at the command line with the <code>install</code> command followed by the name of the package to install, e.g.: <code>npm install nameOfPackage</code>.</p>
<p>As mentioned, it is rarely a good idea to install packages globally at the exception of very few packages, such as command-line applications used across the machine. As an example, the <a href="https://docsify.js.org/">docsify-cli</a> package for documentation generation can safely be installed globally as it is used at the command line in projects that don’t necessarily use NPM. This can be achieved with the <code>-g</code> flag that stands for “global”: <code>npm install docsify-cli -g</code>.</p>
<p>There are two other scopes on which packages can be installed. NPM allows distinguishing between packages that are needed to develop the project and packages that are needed in the final product being built.</p>
<p>R does not come with such convenience but it could perhaps be useful. For instance throughout the book we used the usethis package to develop packages from setting it up to adding packages to the <code>DESCRIPTION</code> file, and more. Perhaps one would like to make this a “developer” dependency so that other developers that pull the package from GitHub have usethis installed and readily available. The advantage is that this dependency would not be included in the final product, that is, usethis is not required to use the package (only to develop it) and therefore is not installed by the user.</p>
<p>As stated in the previous chapter, file size matters in JavaScript; it is, therefore, crucial that dependencies that are used only for development are not included in the final JavaScript file. With NPM this can be done by using the <code>--save-dev</code> flag, e.g.: <code>npm install webpack --save-dev</code> to install webpack. This is how it will be eventually installed as it is needed to prepare the final product (minify, bundle, etc.) but is not required to run the bundled file(s).</p>
<p>Finally, there are the “true” dependencies, those that are needed in the output we’re creating. For instance, were we to rebuild the gio widget using NPM we could install it with <code>npm install giojs --save</code> because this dependency will be required in the output file we produce.</p>
<p>Before moving on to the next section, let us install webpack and its command-line interface as developer dependencies.</p>
<div class="sourceCode" id="cb400"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb400-1" title="1"><span class="ex">npm</span> install webpack webpack-cli --save-dev</a></code></pre></div>
<p>Notice that this updated the <code>package.json</code> file and created the <code>package-lock.json</code> file as well as a <code>node_modules</code> directory to obtain the following structure.</p>
<pre><code>.
├── app.R
├── node_modules
├── package-lock.json
└── package.json</code></pre>
<p>The directory <code>node_modules</code> actually holds all the dependencies, and it will grow in size as you add more, it’s important that this directory is not pushed to whatever version control system you happen use (GitHub, Bitbucket, Gitlab).</p>
<div class="rmdnote">
<p>
Exclude the <code>node_modules</code> directory from your version control (Git or otherwise)
</p>
</div>
<p>The dependencies are anyway not needed as one can pull the project without the <code>node_modules</code> then from the root of the project run <code>npm install</code> to install the dependencies that are listed in the <code>package.json</code> file. We can indeed observe that this file was updated to include <code>webpack</code> and <code>webpack-cli</code> as <code>devDependencies</code>, at the bottom of the file.</p>
<div class="sourceCode" id="cb402"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb402-1" title="1"><span class="fu">{</span></a>
<a class="sourceLine" id="cb402-2" title="2">  <span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;name-of-your-project&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb402-3" title="3">  <span class="dt">&quot;version&quot;</span><span class="fu">:</span> <span class="st">&quot;1.0.0&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb402-4" title="4">  <span class="dt">&quot;description&quot;</span><span class="fu">:</span> <span class="st">&quot;&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb402-5" title="5">  <span class="dt">&quot;main&quot;</span><span class="fu">:</span> <span class="st">&quot;index.js&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb402-6" title="6">  <span class="dt">&quot;scripts&quot;</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb402-7" title="7">    <span class="dt">&quot;test&quot;</span><span class="fu">:</span> <span class="st">&quot;echo </span><span class="ch">\&quot;</span><span class="st">Error: no test specified</span><span class="ch">\&quot;</span><span class="st"> &amp;&amp; exit 1&quot;</span></a>
<a class="sourceLine" id="cb402-8" title="8">  <span class="fu">},</span></a>
<a class="sourceLine" id="cb402-9" title="9">  <span class="dt">&quot;keywords&quot;</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb402-10" title="10">  <span class="dt">&quot;author&quot;</span><span class="fu">:</span> <span class="st">&quot;&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb402-11" title="11">  <span class="dt">&quot;license&quot;</span><span class="fu">:</span> <span class="st">&quot;ISC&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb402-12" title="12">  <span class="dt">&quot;devDependencies&quot;</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb402-13" title="13">    <span class="dt">&quot;webpack&quot;</span><span class="fu">:</span> <span class="st">&quot;^5.2.0&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb402-14" title="14">    <span class="dt">&quot;webpack-cli&quot;</span><span class="fu">:</span> <span class="st">&quot;^4.1.0&quot;</span></a>
<a class="sourceLine" id="cb402-15" title="15">  <span class="fu">}</span></a>
<a class="sourceLine" id="cb402-16" title="16"><span class="fu">}</span></a></code></pre></div>
<p>The <code>package-lock.json</code> file is automatically generated and <em>should not be edited manually.</em> It describes the exact tree of all the dependencies. If you installed a package by mistake, you could uninstall it with <code>npm uninstall nameOfPage</code>.</p>
<p><strong>Recap</strong></p>
<ul>
<li>Install packages globally with <code>npm install package -g</code></li>
<li>Install developer dependencies with <code>npm install package --save-dev</code></li>
<li>Install dependencies required in the output with <code>npm install package --save</code></li>
<li>Uninstall packages with <code>npm uninstall package</code></li>
</ul>
</div>
<div id="webpack-intro-entry-points" class="section level2">
<h2><span class="header-section-number">21.5</span> Entry Point and Output</h2>
<p>In general, an NPM project with webpack will make use of an <code>src</code> directory where the source code is placed and a <code>dist</code> directory (for distributed) where the bundled source code will be placed; we’ll see how to change these defaults later on. It will eventually be necessary as the <code>src</code> directory in R packages is reserved for compiled code (e.g., C++) and therefore cannot be used to place JavaScript files.</p>
<p>It will not be a problem here as we are not building a package.</p>
<div class="sourceCode" id="cb403"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb403-1" title="1"><span class="kw">dir.create</span>(<span class="st">&quot;src&quot;</span>)</a></code></pre></div>
<p>Webpack will then require at least one “entry point.” An entry point is an input file in the <code>src</code> directory that webpack will use as a source to produce the bundle. Let’s create the go-to “hello world” of JavaScript; the snippet below creates the <code>index.js</code> file with a basic vanilla JavaScript alert.</p>
<div class="sourceCode" id="cb404"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb404-1" title="1"><span class="kw">writeLines</span>(<span class="st">&quot;alert(&#39;hello webpack!&#39;)&quot;</span>, <span class="st">&quot;src/index.js&quot;</span>) </a></code></pre></div>
<p>The next section on configuration will detail precisely how to indicate to webpack that this is indeed the entry point it should use.</p>
</div>
<div id="webpack-intro-conf" class="section level2">
<h2><span class="header-section-number">21.6</span> Configuration File</h2>
<p>Webpack comes with a configuration file, <code>webpack.config.js</code>. Though for a larger project it is advised to split it into multiple configuration files (more on that later). This file can include numerous options, plugins, and other settings to customise how webpack transforms the entry point into an output, only some of which will be explored in this book as there are too many to cover.</p>
<p>Below is probably the most straightforward configuration file one may create. At the bare minimum, the configuration file will need to have an entry point specified; in this case, the previously-created <code>index.js</code> file. If no <code>output</code> path is specified, then webpack will produce it at <code>dist/main.js</code> automatically.</p>
<div class="sourceCode" id="cb405"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb405-1" title="1"><span class="co">// webpack.config.js</span></a>
<a class="sourceLine" id="cb405-2" title="2"><span class="va">module</span>.<span class="at">exports</span> <span class="op">=</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb405-3" title="3">  <span class="dt">entry</span><span class="op">:</span> <span class="st">&#39;./src/index.js&#39;</span></a>
<a class="sourceLine" id="cb405-4" title="4"><span class="op">};</span></a></code></pre></div>
<p>The <code>module.exports</code> line may confuse; it is covered in a later section on <em>importing and exporting</em> variables and functions.</p>
</div>
<div id="webpack-intro-npm-scripts" class="section level2">
<h2><span class="header-section-number">21.7</span> NPM scripts</h2>
<p>NPM scripts allow automating development tasks such as running unit tests, serving files, and more, we’ll set it up to run webpack. The scripts are placed in the <code>package.json</code> file and are terminal commands.</p>
<p>By default <code>npm-init</code> creates the following <code>test</code> script, which echoes (prints) a message stating that no unit tests were set up.</p>
<div class="sourceCode" id="cb406"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb406-1" title="1"><span class="er">&quot;scripts&quot;:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb406-2" title="2">  <span class="dt">&quot;test&quot;</span><span class="fu">:</span> <span class="st">&quot;echo </span><span class="ch">\&quot;</span><span class="st">Error: no test specified</span><span class="ch">\&quot;</span><span class="st"> &amp;&amp; exit 1&quot;</span></a>
<a class="sourceLine" id="cb406-3" title="3"><span class="fu">}</span></a></code></pre></div>
<p>This script can be run from the terminal by typing <code>npm run test</code>. Those commands always follow the same pattern: <code>npm run</code> followed by the name of the script, in this case, <code>test</code>.</p>
<p>Adding the script to run webpack is very straightforward, we can add an entry called <code>build</code> that runs <code>webpack</code>.</p>
<div class="sourceCode" id="cb407"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb407-1" title="1"><span class="er">&quot;scripts&quot;:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb407-2" title="2">  <span class="dt">&quot;test&quot;</span><span class="fu">:</span> <span class="st">&quot;echo </span><span class="ch">\&quot;</span><span class="st">Error: no test specified</span><span class="ch">\&quot;</span><span class="st"> &amp;&amp; exit 1&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb407-3" title="3">  <span class="dt">&quot;build&quot;</span><span class="fu">:</span> <span class="st">&quot;webpack&quot;</span></a>
<a class="sourceLine" id="cb407-4" title="4"><span class="fu">}</span></a></code></pre></div>
<p>So running <code>npm run build</code> produces the output file from the entry point file. However, we will modify this slightly in the next section as more features of webpack are uncovered.</p>
</div>
<div id="webpack-intro-webpack-mode" class="section level2">
<h2><span class="header-section-number">21.8</span> Source maps</h2>
<p>We will improve upon the previous section so we can run webpack on two different modes: one for production and one for development.</p>
<p>Since the output of webpack is any number of files bundled into one, it can make debugging more difficult. When files <code>a.js</code>, <code>b.js</code>, and <code>c.js</code> are bundled into <code>dist/main.js</code>, the stack trace will point to errors in <code>dist/main.js</code>, which is not helpful as the developer needs to know in which original file the bug lies.</p>
<p>Therefore, webpack comes with a “development” mode that allows including the “source map,” which maps the compiled code to the source files. This way, when an error or warning is raised JavaScript is able to point to the original line of code that causes it.</p>
<p>There are again many different ways to set this up in the configuration file as the source map can be placed in the bundled file itself, in another file, and more. However, the easiest way is probably to specify the mode using webpack’s CLI tool. The source maps are optional as these make the output larger and one wants to keep this output as small as possible for it to load as fast as possible in web browsers. Those will thus only be used while developing the project to trace back errors and warnings but will not be included in the final output for production.</p>
<p>Below we modify the scripts placed in the <code>package.json</code> file so two different scripts can be run: one for development and another for production.</p>
<div class="sourceCode" id="cb408"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb408-1" title="1"><span class="er">&quot;scripts&quot;:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb408-2" title="2">  <span class="dt">&quot;test&quot;</span><span class="fu">:</span> <span class="st">&quot;echo </span><span class="ch">\&quot;</span><span class="st">Error: no test specified</span><span class="ch">\&quot;</span><span class="st"> &amp;&amp; exit 1&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb408-3" title="3">  <span class="dt">&quot;build-prod&quot;</span><span class="fu">:</span> <span class="st">&quot;webpack --mode=production&quot;</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb408-4" title="4">  <span class="dt">&quot;build-dev&quot;</span><span class="fu">:</span> <span class="st">&quot;webpack --mode=development&quot;</span></a>
<a class="sourceLine" id="cb408-5" title="5"><span class="fu">}</span></a></code></pre></div>
<p>This allows running <code>npm run build-prod</code> to produce the production bundle and <code>npm run build-dev</code> to produce the development version that includes the source map.</p>
</div>
<div id="webpack-intro-bundle" class="section level2">
<h2><span class="header-section-number">21.9</span> Bundle</h2>
<p>One can then bundle the code using the scripts that we defined to produce the output bundle. Since we have not specified any <code>output</code> in webpack’s configuration file, it will create it at the default location <code>dist/main.js</code>.</p>
<div class="sourceCode" id="cb409"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb409-1" title="1"><span class="ex">npm</span> run build-prod</a></code></pre></div>
<p>We can then include the output of webpack in the Shiny application to test that all works well.</p>
<div class="sourceCode" id="cb410"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb410-1" title="1"><span class="kw">library</span>(shiny)</a>
<a class="sourceLine" id="cb410-2" title="2"></a>
<a class="sourceLine" id="cb410-3" title="3">mainJs &lt;-<span class="st"> </span>htmltools<span class="op">::</span><span class="kw">htmlDependency</span>(</a>
<a class="sourceLine" id="cb410-4" title="4">  <span class="dt">name =</span> <span class="st">&quot;main&quot;</span>,</a>
<a class="sourceLine" id="cb410-5" title="5">  <span class="dt">version =</span> <span class="st">&quot;1.0.0&quot;</span>,</a>
<a class="sourceLine" id="cb410-6" title="6">  <span class="dt">src =</span> <span class="st">&quot;./dist&quot;</span>,</a>
<a class="sourceLine" id="cb410-7" title="7">  <span class="dt">script =</span> <span class="kw">c</span>(<span class="dt">file =</span> <span class="st">&quot;main.js&quot;</span>)</a>
<a class="sourceLine" id="cb410-8" title="8">)</a>
<a class="sourceLine" id="cb410-9" title="9"></a>
<a class="sourceLine" id="cb410-10" title="10">ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</a>
<a class="sourceLine" id="cb410-11" title="11">  mainJs,</a>
<a class="sourceLine" id="cb410-12" title="12">  <span class="kw">h1</span>(<span class="st">&quot;A shiny app&quot;</span>)</a>
<a class="sourceLine" id="cb410-13" title="13">)</a>
<a class="sourceLine" id="cb410-14" title="14"></a>
<a class="sourceLine" id="cb410-15" title="15">server &lt;-<span class="st"> </span><span class="cf">function</span>(...) {}</a>
<a class="sourceLine" id="cb410-16" title="16"></a>
<a class="sourceLine" id="cb410-17" title="17"><span class="kw">shinyApp</span>(ui, server)</a></code></pre></div>
<p>Running the above launches the app, which presents the <code>alert()</code> that was placed in the <code>index.js</code> source file.</p>
<p>This makes for a great start but is not precisely interesting; in the following sections, we elaborate on this basic configuration to make better use of webpack’s feature and produce something much more fun.</p>
</div>
<div id="webpack-intro-internal-dependencies" class="section level2">
<h2><span class="header-section-number">21.10</span> Internal Dependencies</h2>
<p>Let’s install a dependency and use it in our Shiny application.</p>
<p>We’ll install <a href="https://github.com/ccampbell/mousetrap">mousetrap,</a> a library to handle key-strokes. We’re going to use it to hide the UI of the Shiny application behind a secret pass-phrase; it will only be revealed after it has been typed. This can be done by observing a specific set of key-strokes with mousetrap and set a Shiny input value when that particular sequence is typed.</p>
<div class="rmdnote">
<p>
This is by no means a safe way to secure an application!
</p>
</div>
<p>Though it is certainly not a real-world example, it is educational and quite a bit of fun.</p>
<p>The first thing to do is to install the mousetrap dependency; as indicated on the <a href="https://github.com/ccampbell/mousetrap">GitHub README</a> it can be obtained from NPM.</p>
<div class="sourceCode" id="cb411"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb411-1" title="1"><span class="ex">npm</span> install mousetrap --save</a></code></pre></div>
<p>Note that we use <code>--save</code> as mousetrap will need to be included in the output we create, it’s not a library we import for development purposes.</p>
</div>
<div id="webpack-intro-external-dependencies" class="section level2">
<h2><span class="header-section-number">21.11</span> External Dependencies</h2>
<p>If dependencies with webpack have to be installed from NPM it begs the question; what about dependencies that are already included in the project and are not available on NPM.</p>
<p>For instance, this project is intended to work with a Shiny application, which comes bundled with jQuery, and the Shiny JavaScript library. First, the Shiny javaScript library is not available on NPM. Second installing it would result in duplicating dependencies, which is hardly best practice. Thankfully webpack comes with a simple mechanism to handle these cases; external dependencies can be added to the configuration file under <code>externals</code>.</p>
<div class="sourceCode" id="cb412"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb412-1" title="1"><span class="va">module</span>.<span class="at">exports</span> <span class="op">=</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb412-2" title="2">  <span class="dt">entry</span><span class="op">:</span> <span class="st">&#39;./src/index.js&#39;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb412-3" title="3">  <span class="dt">externals</span><span class="op">:</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb412-4" title="4">    <span class="dt">shiny</span><span class="op">:</span> <span class="st">&#39;Shiny&#39;</span></a>
<a class="sourceLine" id="cb412-5" title="5">  <span class="op">}</span></a>
<a class="sourceLine" id="cb412-6" title="6"><span class="op">};</span></a></code></pre></div>
<p>The above will allow importing the <code>Shiny</code> object in scripts, which is needed to set the input value with <code>Shiny.setInputValue</code>; hence <code>Shiny</code> must be accessible in webpack. Let us delve into the import/export mechanism.</p>
</div>
<div id="webpack-intro-import-export" class="section level2">
<h2><span class="header-section-number">21.12</span> Import and Export</h2>
<p>To demonstrate how webpack enables modularising code, we will not place all the code in the <code>index.js</code> file. We create two other files: <code>secret.js</code> and <code>input.js</code>. The first will contain the pass-phrase and the second will have the code to handle the key strokes via mousetrap and set the Shiny input. This will enable using the pass-phrase in multiple places without duplicating code.</p>
<div class="sourceCode" id="cb413"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb413-1" title="1"><span class="kw">file.create</span>(<span class="st">&quot;src/input.js&quot;</span>)</a>
<a class="sourceLine" id="cb413-2" title="2"><span class="kw">file.create</span>(<span class="st">&quot;src/secret.js&quot;</span>)</a></code></pre></div>
<p>Therefore, as shown in Figure <a href="webpack-intro-discover.html#fig:webpack-shiny">21.1</a>, the entry point <code>index.js</code> needs to import the <code>input.js</code> file, which itself imports the pass-phrase from <code>secret.js</code>.</p>
<div class="figure" style="text-align: center"><span id="fig:webpack-shiny"></span>
<div id="htmlwidget-1857417b339e6c54d99e" style="width:100%;height:250px;" class="grViz html-widget"></div>
<script type="application/json" data-for="htmlwidget-1857417b339e6c54d99e">{"x":{"diagram":"\ndigraph {\n  graph [rankdir = LR compound=true]\n  node [shape=box]\n\n  subgraph cluster0 {\n    shiny [label=\"import shiny\"]\n    label = \"input.js\"\n    color=gold\n  }\n\n  subgraph cluster1 {\n    passphrase [label=\"export var\"]\n    label = \"secret.js\"\n    color=gold\n  }\n\n  shiny -> \"index.js\" [label=\"import module\", ltail=cluster0]\n  passphrase -> shiny [label=\"import variable\", ltail=cluster1, lhead=cluster0]\n  \"externals\" -> shiny [label=\"import shiny\", lhead=cluster0]\n\n}\n","config":{"engine":"dot","options":null}},"evals":[],"jsHooks":[]}</script>
<p class="caption">
FIGURE 21.1: Webpack with Shiny
</p>
</div>
<p>Again, there are multiple ways to import and export modules, functions, variables, etc. This book will use the ES6 syntax as <a href="https://webpack.js.org/api/module-methods/#es6-recommended">recommended by webpack.</a> Though this mechanism is present in other languages, such as Python (where it somewhat resembles ES6), it will take some getting used to for R programmers as though this language features some form of import (<code>library()</code>) and export (<code>@export</code> roxygen2 tag), this differs significantly from how it works in webpack. This is, however, key to using webpack, as it is what ultimately enables the creation of modules that make code more robust.</p>
<p>There are two different kinds of exports and imports possible, “named” and “default.” We shall cover them in that order.</p>
<div id="webpack-intro-import-export-named" class="section level3">
<h3><span class="header-section-number">21.12.1</span> Named</h3>
<p>Let’s place the variable <code>secret</code> in the <code>secret.js</code> file. As a reminder, this variable will have to be imported by in another file (<code>input.js</code>) where it will be used to check if the pass-phrase typed by the user is correct.</p>
<p>Declaring the variable itself does not change, we use the keyword <code>let</code> to declare a variable named <code>secret</code> that holds the pass-phrase. The issue is that with webpack, this variable will be internal to the file where it is declared. However, we ultimately want to import that variable in another file. To do so, we can place the keyword <code>export</code> in front of the declaration to indicate that this variable is exported from the file. Note that this will also work with functions and classes, and other objects.</p>
<p>Placing <code>export</code> in front of an object constitutes a <em>named export</em>; the <code>secret.js</code> file explicitly exports the variable named <code>secret</code>.</p>
<div class="sourceCode" id="cb414"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb414-1" title="1"><span class="im">export</span> <span class="kw">let</span> secret <span class="op">=</span> <span class="st">&#39;s e c r e t&#39;</span><span class="op">;</span></a></code></pre></div>
<p>Then this variable can be imported in the <code>input.js</code> file. The named export in <code>secret.js</code> comes with a corresponding named import in <code>input.js</code> to import the variable named <code>secret</code>; this is indicated by the curly braces. Note that again we include the path to the file (<code>./secret.js</code>), importing from <code>secret.js</code> without the path will fail.</p>
<div class="sourceCode" id="cb415"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb415-1" title="1"><span class="im">import</span> <span class="op">{</span> secret <span class="op">}</span> <span class="im">from</span> <span class="st">&#39;./secret.js&#39;</span><span class="op">;</span></a></code></pre></div>
<p>The curly braces are used for named imports as multiple such variables or functions can then be imported, e.g., <code>import { foo, bar } from './file.js';</code> to import the named exports <code>foo</code> and <code>bar</code> from <code>file.js</code>.</p>
</div>
<div id="webpack-intro-import-export-default" class="section level3">
<h3><span class="header-section-number">21.12.2</span> Default</h3>
<p>An alternative would be to use a default export. A file can have a default export; said default could be a variable, a function, a list, or any number of things but <em>there can only be a single default export per file</em>.</p>
<div class="sourceCode" id="cb416"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb416-1" title="1"><span class="co">// declare</span></a>
<a class="sourceLine" id="cb416-2" title="2"><span class="kw">let</span> secret <span class="op">=</span> <span class="st">&#39;s e c r e t&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb416-3" title="3"></a>
<a class="sourceLine" id="cb416-4" title="4"><span class="co">// export</span></a>
<a class="sourceLine" id="cb416-5" title="5"><span class="im">export</span> <span class="im">default</span> secret<span class="op">;</span></a></code></pre></div>
<p>Rather interestingly, because multiple variables can be declared on a single line (e.g., <code>var a,b,c;</code>) but only a single default can exist, the default export and vriable declaration cannot be placed on a single line.</p>
<div class="sourceCode" id="cb417"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb417-1" title="1"><span class="co">// invalid</span></a>
<a class="sourceLine" id="cb417-2" title="2"><span class="im">export</span> <span class="im">default</span> secret <span class="op">=</span> <span class="st">&#39;s e c r e t&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb417-3" title="3"></a>
<a class="sourceLine" id="cb417-4" title="4"><span class="co">// valid</span></a>
<a class="sourceLine" id="cb417-5" title="5"><span class="kw">var</span> x <span class="op">=</span> <span class="dv">0</span><span class="op">,</span></a>
<a class="sourceLine" id="cb417-6" title="6">    y <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></a>
<a class="sourceLine" id="cb417-7" title="7"></a>
<a class="sourceLine" id="cb417-8" title="8"><span class="im">export</span> <span class="im">default</span> <span class="op">{</span>x<span class="op">,</span> y<span class="op">}</span></a></code></pre></div>
<p>This only applies to variables as only a single function can be declared by line so declaring a function and its default export on athe same line is valid.</p>
<div class="sourceCode" id="cb418"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb418-1" title="1"><span class="co">// valid</span></a>
<a class="sourceLine" id="cb418-2" title="2"><span class="im">export</span> <span class="im">default</span> <span class="kw">function</span> <span class="at">sayHello</span>() <span class="op">{</span></a>
<a class="sourceLine" id="cb418-3" title="3">  <span class="at">alert</span>(<span class="st">&quot;Hello!&quot;</span>)</a>
<a class="sourceLine" id="cb418-4" title="4"><span class="op">};</span></a></code></pre></div>
<p>Importing default exports in other files resembles all too much the syntax of named imports, which may lead to confusion: it’s essentially the same omitting the curly braces.</p>
<div class="sourceCode" id="cb419"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb419-1" title="1"><span class="im">import</span> secret <span class="im">from</span> <span class="st">&#39;./secret.js&#39;</span><span class="op">;</span></a></code></pre></div>
</div>
<div id="webpack-intro-import-export-wrap-up" class="section level3">
<h3><span class="header-section-number">21.12.3</span> Wrap-up</h3>
<p>We’ll be using a named export method in <code>secret.js</code>. The same general logic can be applied to import the external dependency Shiny as well as mousetrap.</p>
<div class="sourceCode" id="cb420"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb420-1" title="1"><span class="im">import</span> Shiny <span class="im">from</span> <span class="st">&#39;shiny&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb420-2" title="2"><span class="im">import</span> <span class="op">{</span> secret <span class="op">}</span> <span class="im">from</span> <span class="st">&#39;./secret.js&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb420-3" title="3"><span class="im">import</span> Mousetrap <span class="im">from</span> <span class="st">&#39;mousetrap&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb420-4" title="4"></a>
<a class="sourceLine" id="cb420-5" title="5"><span class="va">Mousetrap</span>.<span class="at">bind</span>(secret<span class="op">,</span> <span class="kw">function</span>() <span class="op">{</span> </a>
<a class="sourceLine" id="cb420-6" title="6">  <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="st">&#39;secret&#39;</span><span class="op">,</span> <span class="kw">true</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb420-7" title="7"><span class="op">}</span>)<span class="op">;</span></a></code></pre></div>
<p>Finally, remember to import <code>input.js</code> in the entry point <code>index.js</code>.</p>
<div class="sourceCode" id="cb421"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb421-1" title="1"><span class="co">// index.js</span></a>
<a class="sourceLine" id="cb421-2" title="2"><span class="im">import</span> <span class="st">&#39;./input.js&#39;</span><span class="op">;</span></a></code></pre></div>
<p>This can then be bundled with <code>npm run bundle-prod</code>, which will start at the entry point (<code>index.js</code>) observe that it imports the file <code>input.js</code>, then look at that file and see that it imports <code>secret.js</code>; webpack builds this dependency tree and includes all that is needed in the bundle.</p>
<p>This can be used in the Shiny application, which we modify so it listens to the <code>secret</code> input and only when that input is set renders a plot and a message.</p>
<div class="sourceCode" id="cb422"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb422-1" title="1"><span class="kw">library</span>(shiny)</a>
<a class="sourceLine" id="cb422-2" title="2"></a>
<a class="sourceLine" id="cb422-3" title="3">mainJs &lt;-<span class="st"> </span>htmltools<span class="op">::</span><span class="kw">htmlDependency</span>(</a>
<a class="sourceLine" id="cb422-4" title="4">  <span class="dt">name =</span> <span class="st">&quot;main&quot;</span>,</a>
<a class="sourceLine" id="cb422-5" title="5">  <span class="dt">version =</span> <span class="st">&quot;1.0.0&quot;</span>,</a>
<a class="sourceLine" id="cb422-6" title="6">  <span class="dt">src =</span> <span class="st">&quot;./dist&quot;</span>,</a>
<a class="sourceLine" id="cb422-7" title="7">  <span class="dt">script =</span> <span class="kw">c</span>(<span class="dt">file =</span> <span class="st">&quot;main.js&quot;</span>)</a>
<a class="sourceLine" id="cb422-8" title="8">)</a>
<a class="sourceLine" id="cb422-9" title="9"></a>
<a class="sourceLine" id="cb422-10" title="10">ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</a>
<a class="sourceLine" id="cb422-11" title="11">  mainJs,</a>
<a class="sourceLine" id="cb422-12" title="12">  <span class="kw">p</span>(<span class="st">&quot;Type the secret phrase&quot;</span>),</a>
<a class="sourceLine" id="cb422-13" title="13">  <span class="kw">uiOutput</span>(<span class="st">&quot;hello&quot;</span>),</a>
<a class="sourceLine" id="cb422-14" title="14">  <span class="kw">plotOutput</span>(<span class="st">&quot;plot&quot;</span>)</a>
<a class="sourceLine" id="cb422-15" title="15">)</a>
<a class="sourceLine" id="cb422-16" title="16"></a>
<a class="sourceLine" id="cb422-17" title="17">server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output) {</a>
<a class="sourceLine" id="cb422-18" title="18">  output<span class="op">$</span>hello &lt;-<span class="st"> </span><span class="kw">renderUI</span>({</a>
<a class="sourceLine" id="cb422-19" title="19">    <span class="kw">req</span>(input<span class="op">$</span>secret)</a>
<a class="sourceLine" id="cb422-20" title="20">    <span class="kw">h2</span>(<span class="st">&quot;You got the secret right!&quot;</span>)</a>
<a class="sourceLine" id="cb422-21" title="21">  })</a>
<a class="sourceLine" id="cb422-22" title="22"></a>
<a class="sourceLine" id="cb422-23" title="23">  output<span class="op">$</span>plot &lt;-<span class="st"> </span><span class="kw">renderPlot</span>({</a>
<a class="sourceLine" id="cb422-24" title="24">    <span class="kw">req</span>(input<span class="op">$</span>secret)</a>
<a class="sourceLine" id="cb422-25" title="25">    <span class="kw">hist</span>(cars<span class="op">$</span>speed)</a>
<a class="sourceLine" id="cb422-26" title="26">  })</a>
<a class="sourceLine" id="cb422-27" title="27">}</a>
<a class="sourceLine" id="cb422-28" title="28"></a>
<a class="sourceLine" id="cb422-29" title="29"><span class="kw">shinyApp</span>(ui, server)</a></code></pre></div>
<p>Once the application is launched the user can type the phrase <code>secret</code> to see the content of the application (see Figure <a href="webpack-intro-discover.html#fig:mousetrap">21.2</a>).</p>
<div class="figure" style="text-align: center"><span id="fig:mousetrap"></span>
<img src="images/mousetrap.png" alt="Mousetrap example" width="100%" />
<p class="caption">
FIGURE 21.2: Mousetrap example
</p>
</div>
<p>That is it for this chapter. As stated multiple times there is far more depth to webpack, but this is outside the scope of this book, instead in the next chapter we discover an easier way to set up such projects and make R and webpack work in a more seamless fashion.</p>

</div>
</div>
</div>
<h3>References</h3>
<div id="refs" class="references">
<div id="ref-R-renv">
<p>Ushey, Kevin. 2020. <em>Renv: Project Environments</em>. <a href="https://CRAN.R-project.org/package=renv">https://CRAN.R-project.org/package=renv</a>.</p>
</div>
<div id="ref-R-packrat">
<p>Ushey, Kevin, Jonathan McPherson, Joe Cheng, Aron Atkins, and JJ Allaire. 2018. <em>Packrat: A Dependency Management System for Projects and Their R Package Dependencies</em>. <a href="https://CRAN.R-project.org/package=packrat">https://CRAN.R-project.org/package=packrat</a>.</p>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="webpack-intro.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="packer-overview.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook-2.6.7/js/app.min.js"></script>
<script src="libs/gitbook-2.6.7/js/lunr.js"></script>
<script src="libs/gitbook-2.6.7/js/clipboard.min.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-search.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-sharing.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-bookdown.js"></script>
<script src="libs/gitbook-2.6.7/js/jquery.highlight.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/7-02-webpack-npm-discover.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
